#include "MainWindow.h"

/*-----------------------------------------------------------------------------
 *  Carrega uma memória
 *-----------------------------------------------------------------------------*/
bool MainWindow::loadMemory(const QString& file, MemoryPtr& memory, QListWidget *patternList)
{
    patternList->clear();

    string filename(file.toUtf8().constData());

    try
    {
        memory = Parser::parse(filename);

        for(uint i = 0; i < memory->size(); i++)
        {
            new QListWidgetItem(patternList);
            QListWidgetItem *item = patternList->item(i);
            item->setText("Pattern " + QString::number(i+1));
        }

        patternList->setCurrentRow(0);
        patternList->setFocus();
        return true;
    }
    catch(ParseException& ex)
    {
        QErrorMessage *error = new QErrorMessage;
        error->showMessage(ex.what());
    }

    return false;
}

/*-----------------------------------------------------------------------------
 *  Desenha um padrão
 *-----------------------------------------------------------------------------*/
void MainWindow::drawPattern(MemoryPtr& memory, QListWidget *patternList, PatternView *patternView)
{
    int row = patternList->currentRow();
    PatternPtr pat = memory->at(row);

    patternView->setGrid(pat->rows);

    for(uint i = 0; i < pat->rows; i++)
        for(uint j = 0; j < pat->cols; j++)
            if(pat->at(i, j) == 1)
                patternView->set(i, j);
}

/*-----------------------------------------------------------------------------
 *  Desenha um padrão
 *-----------------------------------------------------------------------------*/
void MainWindow::drawPattern(PatternPtr& pat, PatternView *patternView)
{
    patternView->setGrid(pat->rows);

    for(uint i = 0; i < pat->rows; i++)
        for(uint j = 0; j < pat->cols; j++)
            if(pat->at(i, j) == 1)
                patternView->set(i, j);
}

/*-----------------------------------------------------------------------------
 *  Vai para o próximo padrão
 *-----------------------------------------------------------------------------*/
void MainWindow::nextPattern(QListWidget *patternList)
{
    int row = patternList->currentRow();
    if(row < patternList->count() - 1)
        patternList->setCurrentRow(row + 1);
    patternList->setFocus();
}

/*-----------------------------------------------------------------------------
 *  Vai para o padrão anterior
 *-----------------------------------------------------------------------------*/
void MainWindow::prevPattern(QListWidget *patternList)
{
    int row = patternList->currentRow();
    if(row > 0)
        patternList->setCurrentRow(row - 1);
    patternList->setFocus();
}

/*-----------------------------------------------------------------------------
 *  Treina a rede Hopfield
 *-----------------------------------------------------------------------------*/
void MainWindow::trainHopfield()
{
    hopfield = HopfieldPtr(new Hopfield);
    hopfield->train(trainMemory);

    uint size = hopfield->size();

    weightTable->setColumnCount(size);
    weightTable->setRowCount(size);

    for(uint i = 0; i < size; i++)
    {
        QTableWidgetItem *row = new QTableWidgetItem;
        row->setText(QString::number(i+1));
        weightTable->setVerticalHeaderItem(i, row);

        QTableWidgetItem *column = new QTableWidgetItem;
        column->setText(QString::number(i+1));
        weightTable->setHorizontalHeaderItem(i, column);

        weightTable->setColumnWidth(i, 30);
        weightTable->setRowHeight(i, 20);
    }

    for(uint i = 0; i < size; i++)
        for(uint j = 0; j < size; j++)
        {
            QTableWidgetItem *item = new QTableWidgetItem;
            item->setText(QString::number(hopfield->at(i, j), 'f', 2));
            weightTable->setItem(i, j, item);
        }
}

/*-----------------------------------------------------------------------------
 *  Testa a rede Hopfieldb
 *-----------------------------------------------------------------------------*/
void MainWindow::testHopfield()
{
    int row = testPatternList->currentRow();
    PatternPtr pat;
    bool done = false;

    hopfield->initTest(testMemory, row, pat);

    for(uint iterations = 1; !done; iterations++)
    {
        done = hopfield->test(pat);
        iterationsLabel->setText("Iterations: " + QString::number(iterations));
        printf("Test Iterations: %d \n", iterations);
    }   

    drawPattern(pat, testOutPatternView);
}
